import math
import talib
import numpy as np

'''
K线解析
'''


class kline_parse():
    frameRecord = {}

    def kLineParse(self, kLine):
        '''
        K线处理
        '''
        timeframe15 = kLine[0]
        timeframe30 = kLine[1]
        timeframe60 = kLine[2]
        timeframe240 = kLine[3]
        return self.beatTogether(timeframe15, timeframe30, timeframe60, timeframe240)

    def beatTogether(self, time15Arr, time30Arr, time60Arr, time240Arr):
        '''
        共振
        '''

        ebs_wu, ebs_shiwu, ebs_sanshi, ebs_liushi = self.movelineForDict(time240Arr)
        liushi_wu, liushi_shiwu, liushi_sanshi, liushi_liushi = self.movelineForDict(time60Arr)
        sanshi_wu, sanshi_shiwu, sanshi_sanshi, sanshi_liushi = self.movelineForDict(time30Arr)
        shiwu_wu, shiwu_shiwu, shiwu_sanshi, shiwu_liushi = self.movelineForDict(time15Arr)

        value = ""
        if shiwu_liushi > shiwu_sanshi > shiwu_shiwu > shiwu_wu:
            if sanshi_liushi > sanshi_sanshi > sanshi_shiwu > sanshi_wu:
                value = "短线:共振下跌;"

        if shiwu_wu > shiwu_shiwu > shiwu_sanshi > shiwu_liushi:
            if sanshi_wu > sanshi_shiwu > sanshi_sanshi > sanshi_liushi:
                value = "短线:共振上涨;"

        if sanshi_liushi > sanshi_sanshi > sanshi_shiwu > sanshi_wu:
            if liushi_liushi > liushi_sanshi > liushi_shiwu > liushi_wu:
                value = value + "中线:共振下跌;"

        if sanshi_wu > sanshi_shiwu > sanshi_sanshi > sanshi_liushi:
            if liushi_wu > liushi_shiwu > liushi_sanshi > liushi_liushi:
                value = value + "中线:共振上涨;"

        if liushi_liushi > liushi_sanshi > liushi_shiwu > liushi_wu:
            if ebs_liushi > ebs_sanshi > ebs_shiwu > ebs_wu:
                value = value + "长线:共振下跌"

        if liushi_wu > liushi_shiwu > liushi_sanshi > liushi_liushi:
            if ebs_wu > ebs_shiwu > ebs_sanshi > ebs_liushi:
                value = value + "长线:共振上涨"

        if value == "":
            return "无"
        return value

    def bollingerBands(self, *kLine, currentPrice):
        """
        布林线状态
        """

        bollValue = ""
        kLine = kLine[0]
        frame15High, frame15Low, frame15Open, frame15Close = kLine[0], kLine[1], kLine[2], kLine[3]
        frame30High, frame30Low, frame30Open, frame30Close = kLine[4], kLine[5], kLine[6], kLine[7]
        frame60High, frame60Low, frame60Open, frame60Close = kLine[8], kLine[9], kLine[10], kLine[11]
        frame240High, frame240Low, frame240Open, frame240Close = kLine[12], kLine[13], kLine[14], kLine[15]

        frame15Upper, frame15Middle, frame15Lower = talib.BBANDS(np.array(self.arrayTypeChange(frame15Close)),
                                                                 timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
        frame30Upper, frame30Middle, frame30Lower = talib.BBANDS(np.array(self.arrayTypeChange(frame30Close)),
                                                                 timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
        frame60Upper, frame60Middle, frame60Lower = talib.BBANDS(np.array(self.arrayTypeChange(frame60Close)),
                                                                 timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
        frame240Upper, frame240Middle, frame240Lower = talib.BBANDS(np.array(self.arrayTypeChange(frame240Close)),
                                                                    timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)

        centor15 = self.bollCentorLine(frame15Lower, frame15Upper, frame15Middle, frame15High, frame15Low, currentPrice)
        centor30 = self.bollCentorLine(frame30Lower, frame30Upper, frame30Middle, frame30High, frame30Low, currentPrice)
        centor60 = self.bollCentorLine(frame60Lower, frame60Upper, frame60Middle, frame60High, frame60Low, currentPrice)
        centor240 = self.bollCentorLine(frame240Lower, frame240Upper, frame240Middle, frame240High, frame240Low,
                                        currentPrice)

        bband15Status = self.bollStatus(frame15Lower, frame15Upper, frame15Middle, currentPrice)
        bband30Status = self.bollStatus(frame30Lower, frame30Upper, frame30Middle, currentPrice)
        bband60Status = self.bollStatus(frame60Lower, frame60Upper, frame60Middle, currentPrice)
        bband240Status = self.bollStatus(frame240Lower, frame240Upper, frame240Middle, currentPrice)

        if bband15Status != "":
            bollValue = "15分钟:" + bband15Status + ";"

        if bband30Status != "":
            bollValue = bollValue + "30分钟:" + bband30Status + ";"

        if bband60Status != "":
            bollValue = bollValue + "60分钟:" + bband60Status + ";"

        if bband240Status != "":
            bollValue = bollValue + "4小时:" + bband240Status
        if bollValue == "":
            return "无", [centor15, centor30, centor60, centor240]
        return bollValue, [centor15, centor30, centor60, centor240]

    def bollStatus(self, lower, upper, middle, price):
        """
        布林线状态
        """
        if self.firstNoZero(lower)[0] > float(price):
            return "下跌"

        if float(price) > self.firstNoZero(upper)[0]:
            return "上涨"

        if self.firstNoZero(middle)[0] + 1 > float(price) > self.firstNoZero(middle)[0] - 1:
            return "中间"
        return ""

    def bollCentorLine(self, lowerArr, upperArr, middleArr, highest, lowest, price):
        """
        当前价格穿过布林中线
        return  1:上穿     2:下穿
        """
        if self.firstNoZero(middleArr)[0] + 1 > float(price) > self.firstNoZero(middleArr)[0] - 1:
            for i in range(len(highest)):
                if self.firstNoZero(lowerArr)[i] > float(lowest[i]):
                    return 1

                if float(highest[i]) > self.firstNoZero(upperArr)[0]:
                    return 2
        return 0

    def movelineForDict(self, dict, arg1=5, arg2=15, arg3=30, arg4=60):
        """
        移动平均线
        """
        return self.MovingAverageValue(dict, arg1), \
               self.MovingAverageValue(dict, arg2), \
               self.MovingAverageValue(dict, arg3), \
               self.MovingAverageValue(dict, arg4)

    def valueForDict(self, dict, arg1="hight", arg2="low", arg3="open", arg4="close"):
        """
        从字典获取数据
        """
        return str(dict[arg1]).split(","), str(dict[arg2]).split(","), str(dict[arg3]).split(","), str(
            dict[arg4]).split(",")

    def continuity(self, *kLine):
        """
        K线涨跌连续性
        """

        valurStr = ""

        kLine = kLine[0]
        frame15High, frame15Low, frame15Open, frame15Close = kLine[0], kLine[1], kLine[2], kLine[3]
        frame30High, frame30Low, frame30Open, frame30Close = kLine[4], kLine[5], kLine[6], kLine[7]
        frame60High, frame60Low, frame60Open, frame60Close = kLine[8], kLine[9], kLine[10], kLine[11]
        frame240High, frame240Low, frame240Open, frame240Close = kLine[12], kLine[13], kLine[14], kLine[15]
        
        open15Arr = self.continuityValue(frame15Open, frame15Close)  # 0.2
        open30Arr = self.continuityValue(frame30Open, frame30Close)  # 0.3
        open60Arr = self.continuityValue(frame60Open, frame60Close)  # 0.4
        open240Arr = self.continuityValue(frame240Open, frame240Close)  # 0.5

        if open15Arr is not None and len(open15Arr) > 2:
            floatValue = self.priceLimit(open15Arr[-1], frame15Close[0])
            # if floatValue > 0.2 or floatValue < -0.2:
            valurStr = "15分钟:" + str(floatValue) + "%;"

        if open30Arr is not None and len(open30Arr) > 2:
            floatValue = self.priceLimit(open30Arr[-1], frame30Close[0])
            # if floatValue > 0.3 or floatValue < -0.3:
            valurStr = valurStr + "30分钟:" + str(floatValue) + "%;"

        if open60Arr is not None and len(open60Arr) > 2:
            floatValue = self.priceLimit(open60Arr[-1], frame60Close[0])
            # if floatValue > 0.4 or floatValue < -0.4:
            valurStr = valurStr + "60分钟:" + str(floatValue) + "%;"

        if open240Arr is not None and len(open240Arr) > 2:
            floatValue = self.priceLimit(open240Arr[-1], frame240Close[0])
            # if floatValue > 0.5 or floatValue < -0.5:
            valurStr = valurStr + "4小时:" + str(floatValue) + "%"

        if valurStr == "":
            return "无"
        return valurStr

    def priceLimit(self, open, lastClose):
        """
        计算涨跌幅，lastClose：最后的收盘价
        """
        return round(float(round((float(lastClose) - float(open)) / float(open), 3) * 1000)) / 10

    def continuityValue(self, openArr, closeArr):
        """
        K线连涨连跌值
        """
        priceArr = []
        priceTag = 0  # 1：首根K线为涨    2：首根K线为跌
        for i in range(0, len(openArr)):
            if openArr[i] > closeArr[i]:
                if i == 0:
                    priceTag = 2
                else:
                    if priceTag == 1:
                        return priceArr
                priceArr.append(openArr[i])
            elif closeArr[i] > openArr[i]:
                if i == 0:
                    priceTag = 1
                else:
                    if priceTag == 2:
                        return priceArr
                priceArr.append(openArr[i])
        return None

    def kArray(self, highArr, lowArr, openArr, closeArr, lenth=30):
        """
        用于形态识别的参数
        """
        lineArray = []
        for i in range(1, lenth):
            lineArray.append({"hight": highArr[i], "low": lowArr[i], "open": openArr[i], "close": closeArr[i]})
        return lineArray

    def strJoint(self, oldStr, newStr):
        '''
        String拼接
        '''
        if oldStr != "":
            return oldStr + "," + newStr
        return newStr

    def getSeriesValue(self, dataframe, timeframe, series, inBarSize=10):

        """
        解析series, 遍历series，拿到name的值
        inBarSize：有效的K线范围
        """

        dataframe["formData"] = series
        seriesArr = dataframe.loc[dataframe["formData"] != 0]["formData"]
        if len(seriesArr) != 0:
            index = seriesArr.index[0]
            if index <= inBarSize:
                global frameRecord
                if seriesArr.iloc[0] == 100:
                    frameValue = self.frameRecord.get(timeframe)
                    if frameValue is None or frameValue != index:
                        self.frameRecord[timeframe] = index
                        print(timeframe + "分钟，下标：" + str(index))
                    return "上涨"

                if seriesArr.iloc[0] == -100:
                    frameValue = self.frameRecord.get(timeframe)
                    if frameValue is None or frameValue != index:
                        self.frameRecord[timeframe] = index
                        print(timeframe + "分钟，下标：" + str(index))
                    return "下跌"
        return ""

    def firstNoZero(self, array):
        """
        去除空数字
        """
        arrValue = []
        for i in range(0, len(array)):
            if not math.isnan(array[i]) and array[i] != "":
                arrValue.append(array[i])
        return arrValue

    def MovingAverageValue(self, closeArr, time):
        '''
        移动平均值
        '''

        Sma = []
        for i in range(time - 1, len(closeArr)):
            value = closeArr[i - (time - 1):(i + 1)]
            Sma.append(sum(self.arrayTypeChange(value)) / time)
        return Sma[0]

    def arrayTypeChange(self, arr):
        """
        string 数组转float数组
        """
        return [float(x) for x in arr]
